# -*- coding: UTF-8 -*-
# @Time : 2021/12/6 0006 16:17
# @Author : lyw
# @Remark :
import logging
import re

from mxsoftpy.exception import DBError

from db.public.IOTManager.iot_base import IOTBaseDB
from index import mini_cache


class UPSSelectDB(IOTBaseDB):
    device_type = "UpsDevice"
    query_field = ["mxlabel", "mxdevicetype", "mxparent"]

    def read_template(self):
        """
        读取设备模板
        @return:
        """
        db_path = "EntityTemplate"
        ups_temp_dict = {}
        ups_temp_cache = mini_cache.get("UPS_TEMP_CACHE")
        if ups_temp_cache:
            logging.info("UPS 模板读取缓存")

            return mini_cache["UPS_TEMP_CACHE"]
        for monitor_sub_code in self.tree.open(db_path, "IOT\\UpsDevice", file="base").sub_keys():
            sub_path = "\\".join(["IOT", "UpsDevice", monitor_sub_code, "MonitorEx"])
            plugin_dict = {"battery": [], "input": [], "output": [], "alert": [], "bypass": []}
            for monitor_key in self.tree.open(db_path, sub_path, file="base").sub_keys():
                monitor_value = self.tree.open(db_path, "\\".join([sub_path, monitor_key]), file="base").items()
                self.query_run_mode(monitor_value["mxpluginname"], plugin_dict)
                monitor = self.regular_monitor(monitor_key)
                if monitor:
                    self.query_plugin_data(monitor_value["mxpluginname"], plugin_dict, monitor)
                    continue

                monitor = self.regular_monitor(monitor_value["mxlabel"])

                if monitor:
                    self.query_plugin_data(monitor_value["mxpluginname"], plugin_dict, monitor)
            else:
                if plugin_dict:
                    ups_temp_dict[monitor_sub_code] = plugin_dict
        mini_cache.set("UPS_TEMP_CACHE", ups_temp_dict, 24 * 60 * 60)
        logging.info("UPS 模板设置了缓存")
        return ups_temp_dict

    def query_plugin_data(self, mxpluginname, plugin_dict, monitor):
        """
        获取 判断
        @param mxpluginname:
        @param plugin_dict:
        @param monitor:
        @return:
        """
        monitor_sub_list = plugin_dict.get(monitor)
        if monitor_sub_list and isinstance(monitor_sub_list, list):
            monitor_sub_dict = {"key": mxpluginname, "monitor": []}
            plugin_dict[monitor].append(monitor_sub_dict)
        else:
            monitor_sub_dict = {"key": mxpluginname, "monitor": []}
            plugin_dict[monitor] = [monitor_sub_dict]
        self.query_temp(mxpluginname, monitor_sub_dict)

    @staticmethod
    def regular_monitor(value):
        """
        匹配 字符
        @param value:
        @return:
        """
        if re.search("电池|battery|batt", value.lower()):
            return "battery"
        if re.search("输入|input", value.lower()):
            return "input"
        if re.search("输出|output", value.lower()):
            return "output"
        if re.search("状态|status", value.lower()):
            return "alert"
        if re.search("旁路|bypass", value.lower()):
            return "bypass"
        if re.search("运行模式|工作模式", value.lower()):
            return "run_mode"

    def query_temp(self, mxpluginname, plugin_list: dict):
        """
        获取 plugin 数据
        @param mxpluginname:
        @param plugin_list:
        @return:
        """
        path = "PluginData"
        try:
            for i in self.tree.open(path, mxpluginname + "\\Output", file="base").sub_keys():
                plugin_data = self.tree.open(path, mxpluginname + "\\Output\\%s" % i, file="base").items(
                    ["mxlabel", "mxunit"])
                plugin_data["key"] = i
                plugin_list["name"] = self.tree.open(path, mxpluginname, file="base").fetchone_value("mxlabel")
                plugin_list["monitor"].append(plugin_data)
        except DBError as e:
            logging.error(e)

    @staticmethod
    def add_field(plugin_list, monitor_key, plugin_data):
        """
        增加字段
        @param plugin_list:
        @param monitor_key:
        @param plugin_data:
        @return:
        """
        if isinstance(plugin_list.get(monitor_key), list):
            plugin_list[monitor_key].append(plugin_data)
        else:
            plugin_list[monitor_key] = [plugin_data]

    def query_run_mode(self, mxpluginname, plugin_list: dict, ):
        """
        获取 plugin 数据
        @param mxpluginname:
        @param plugin_list:
        @return:
        """
        if isinstance(plugin_list.get("run_mode"), dict):
            monitor_list = plugin_list["run_mode"]
        else:
            monitor_list = plugin_list["run_mode"] = {}
        path = "PluginData"
        try:
            for i in self.tree.open(path, mxpluginname + "\\Output", file="base").sub_keys():
                plugin_data = self.tree.open(path, mxpluginname + "\\Output\\%s" % i, file="base").items(
                    ["mxlabel", "mxunit"])
                plugin_data["key"] = i
                plugin_data["plugin"] = mxpluginname
                monitor_key = self.regular_monitor(plugin_data["mxlabel"])
                if monitor_key != "run_mode":
                    continue
                plugin_data["name"] = self.tree.open(path, mxpluginname, file="base").fetchone_value("mxlabel")

                monitor_list.update(plugin_data)
        except DBError as e:
            logging.error(e)

    def get_sub_monitor(self, code, device_data):
        """
        获取设备的监测点信息
        @param device_data:
        @param code:
        @return:
        """
        monitor_res_dict = {}
        try:
            ups_sub_list = self.tree.open("MXSE", "1\\1.SD\\%s\\%s.SubMonitor" % (code, code),
                                          file="ccubase").sub_keys()
            for ups_sub_key in ups_sub_list:
                ups_sub_monitor = self.tree.open("MXSE",
                                                 "1\\1.SD\\%s\\%s.SubMonitor\\%s" % (code, code, ups_sub_key),
                                                 file="ccubase").items(prop_list="mxpluginname")

                monitor_res_dict[ups_sub_key] = ups_sub_monitor["mxpluginname"]
            device_data["sub_monitor"] = monitor_res_dict
        except DBError as e:
            logging.error(e)

    def query_monitor_table_data(self, code, count=1):
        """
        查询记录
        @param count:
        @param code:
        @return:
        """
        try:
            monitor_table_list = self.table.open("MXSE", code).record_by_time(days=100, count=count)
            if monitor_table_list:
                return monitor_table_list[0]
        except DBError as e:
            logging.error(e)

    def param_middle(self, data_obj) -> dict:
        """
        基础查询 参数
        @param data_obj:
        @return:
        """
        return {"iot_code": data_obj.iot_code, "device_type": data_obj.device_type}


class UPSListDB(UPSSelectDB):
    def get_sub_monitor(self, code, device_data):
        pass


class UPSRetrieveDB(UPSSelectDB):
    pass


class UPSTrendDB(UPSRetrieveDB):

    def query_monitor_table_data(self, code, count=0, **kwargs):
        """
        查询记录
        @param count:
        @param code:
        @return:
        """
        try:
            monitor_table_list = self.table.open("MXSE", code).record_by_time(count=count, **kwargs)
            return monitor_table_list
        except DBError as e:
            logging.error(e)
